package com.newy.core.util;

import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.map.ObjectMapper;

/**
 * 语言相关的工具类
 * @author LinZongxue
 *
 */
public class LangUtils {
	/**
	 * 判断对象是否为空。
	 * @param obj 字符串、对象数组或java.util.Collection
	 * @return
	 */
	public static boolean isEmpty(Object obj){
		if (obj == null){
			return true;
		}
		if (obj instanceof String){
			return ((String) obj).trim().equals("");
		}
		if (obj instanceof Object[]){
			return ((Object[]) obj).length == 0;
		}
		if (obj instanceof Collection){
			return ((Collection<?>) obj).isEmpty();
		}
		return false;
	}

	/**
	 * 判断对象是否为非空。
	 * @param obj 字符串、对象数组或java.util.Collection
	 */
	public static boolean isNotEmpty(Object obj){
		return !LangUtils.isEmpty(obj);
	}
	
	/**
	 * md5加密
	 */
	public static String md5(String src){
		if (src == null)
			return null;
		try{
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(src.getBytes());
			StringBuilder dist = new StringBuilder();
			for (byte b : md.digest()){
				String s = Integer.toHexString(0xFF & b);
				if (s.length() == 1) dist.append("0");
				dist.append(s);
			}
			return dist.toString();
		}
		catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 去掉前后空白字符，包括中文空格
	 */
	public static String trimCn(String str){
		if (str == null)
			return null;
		str = str.trim();
		if (str.length() == 0)
			return str;
		int st = 0;
		int len = str.length();
		while((st < len) && str.charAt(st) == '　')
			st ++;
		while((st < len) && str.charAt(len - 1) == '　')
			len --;
		if (st > 0 || len < str.length())
			str = str.substring(st, len);
		return str.trim();
	}
	
	public static boolean contains(Object[] array, Object item){
		for (Object obj : array){
			if (obj.equals(item)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 对某个对象集合，取出每个元素指定属性的值，以数组返回
	 */
	@SuppressWarnings("unchecked")
	public static <X> List<X> filterField(Collection<?> beans, String fieldName){
		if (beans == null || beans.isEmpty()) return new ArrayList<X>(0);
		List<X> result = new ArrayList<X>(beans.size());
		for (Object bean : beans){
			result.add((X)ReflectionUtils.getFieldValue(bean, fieldName));
		}
		return result;
	}
	
	/**
	 * 从对象集合中，根据对象某个指定的属性的值，取得第一个匹配的对象。
	 * @param <X> 对象的类型
	 * @param beans 对象的集合
	 * @param fieldName 指定对象的属性名称
	 * @param fieldValue 指定对象的属性值
	 * @return 第一个匹配的对象
	 */
	public static <X> X findBeanIn(Collection<X> beans, String fieldName, Object fieldValue){
		if (beans == null) return null;
		for (X bean : beans){
			if (fieldValue.equals(ReflectionUtils.getFieldValue(bean, fieldName)))
				return bean;
		}
		return null;
	}
	
	/**
	 * 从对象集合中，将对象某个属性设置为null。
	 * （一般用途是将Hibernate持久对象的延迟加载属性清除，避免将对象转换成json时出错）
	 * @param beans 对象集合
	 * @param fieldName 要设置为null的属性名
	 */
	public static void clearFieldIn(Collection<?> beans, String fieldName){
		if (beans == null) return;
		for (Object bean : beans){
			ReflectionUtils.setFieldValue(bean, fieldName, null);
		}
	}

	/**
	 * 将对象的所有字符串类型的字段中的空格转换为(%)，以方便进行like查询。
	 * 注意：同时也将空字符串字段的值修改为null。
	 * 此方法是为了方便在hibernate中进行Example查询。
	 */
	public static void makeFieldsLike(Object bean){
		if (bean == null) return;
		try{
			for (Field field : bean.getClass().getDeclaredFields()){
				Object value = ReflectionUtils.invokeGetterMethod(bean, field.getName());
				if (value instanceof String){
					String newValue = value.toString().trim();
					newValue = newValue.length() > 0 ? "%" + newValue.replaceAll("\\s", "%") + "%" : null;
					ReflectionUtils.invokeSetterMethod(bean, field.getName(),  newValue, String.class);
				}
			}
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public static String isoToUtf8(String str){
		if (str == null) return null;
		try{
			return new String(str.getBytes("iso_8859_1"), "utf-8");
		}
		catch (Exception e){
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 将对象转换成json字符串。如果只有一个参数则直接转换，否则参数个数必须为偶数，并以奇数参数为属性以偶数参数为值转换。
	 */
	public static String toJson(Object... args){
		try{
			ObjectMapper mapper = new ObjectMapper();
			if (args.length == 0){
				return "null";
			}
			else if (args.length == 1){
				return mapper.writeValueAsString(args[0]);
			}
			if (args.length % 2 != 0){
				throw new RuntimeException("调用BookUtils.toJson()方法参数个数必须为偶数");
			}
			Map<String, Object> map = new HashMap<String, Object>(args.length / 2);
			for (int i = 0; i < args.length; i += 2){
				map.put(args[i].toString(), args[i + 1]);
			}
			return mapper.writeValueAsString(map);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	public static List<?> jsonToList(String json){
		try{
			ObjectMapper mapper = new ObjectMapper();
			return (List<?>)mapper.readValue(json, List.class);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Map<String, ?> jsonToMap(String json){
		try{
			ObjectMapper mapper = new ObjectMapper();
			return (Map<String, ?>)mapper.readValue(json, Map.class);
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 将日期转换成字符串，格式为yyyy-MM-dd HH:mm:ss
	 */
	public static String formatDate(Date date){
		if (date == null) return null;
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
	}
	
	/**
	 * 将日期字符串转换成日期，只支持如下格式：
	 * yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss
	 */
	public static Date parseDate(String str){
		if (str == null) return null;
		try{
			String f = (str.length() == 10 ? "yyyy-MM-dd" : "yyyy-MM-dd HH:mm:ss");
			return new SimpleDateFormat(f).parse(str);
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将字符串转换为Long，转换失败返回null
	 */
	public static Long parseLong(String str){
		return LangUtils.parseLong(str, null);
	}
	
	/**
	 * 将字符串转换为Long，转换失败返回defaultValue
	 */
	public static Long parseLong(String str, Long defaultValue){
		if (str == null) return null;
		try{
			return Long.parseLong(str);
		}
		catch(Exception e){
			
		}
		return defaultValue;
	}
}
